package cn.gx.kevin.common.utils;

import org.apache.commons.lang3.StringUtils;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.text.NumberFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

/**
 * @ClassName: DataUnit
 * @Description: TODO
 * @author kevin.huang
 * @date 2016年4月4日 下午5:02:30
 */
public class DataUtils {

	public static boolean isLetter(char c) {
		int k = 0x80;
		return c / k == 0 ? true : false;
	}

	public static String convertDouble(double d ,Integer dotNum) {
			NumberFormat nf = NumberFormat.getInstance();
			// 是否以逗号隔开, 默认true以逗号隔开,如[123,456,789.36]
			nf.setGroupingUsed(false);
			if(dotNum != null){
				nf.setMinimumFractionDigits( dotNum );
			}
			// 结果未做任何处理
			return nf.format(d);
	}

	public static String convertFloat(float f,Integer dotNum) {
		BigDecimal   b   =   new   BigDecimal(f);
		String   f1   =  String.valueOf( b.setScale(dotNum,   BigDecimal.ROUND_HALF_UP).floatValue());
		return f1;
	}

	/**
	 * 判断字符串是否为空
	 * 
	 * @param str
	 * @return
	 */
	public static boolean isNull(String str) {
		if (StringUtils.isEmpty(str)) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * 得到一个字符串的长度,显示的长度,一个汉字或日韩文长度为2,英文字符长度为1
	 * 
	 * @param String s 需要得到长度的字符串
	 * @return int 得到的字符串长度
	 */
	public static int getStringlength(String s) {
		if (s == null) {
			return 0;
		}

		char[] c = s.toCharArray();
		int len = 0;
		for (int i = 0; i < c.length; i++) {
			len++;
			if (!isLetter(c[i])) {
				len++;
			}
		}
		return len;
	}

	/**
	 * 得到一个字符串的长度,显示的长度,一个汉字或日韩文长度为1,英文字符长度为0.5
	 * 
	 * @param String s 需要得到长度的字符串
	 * @return int 得到的字符串长度
	 */
	public static double getStringLength1(String s) {
		double valueLength = 0;
		String chinese = "[\u4e00-\u9fa5]";
		// 获取字段值的长度，如果含中文字符，则每个中文字符长度为2，否则为1
		for (int i = 0; i < s.length(); i++) {
			// 获取一个字符
			String temp = s.substring(i, i + 1);
			// 判断是否为中文字符
			if (temp.matches(chinese)) {
				// 中文字符长度为1
				valueLength += 1;
			} else {
				// 其他字符长度为0.5
				valueLength += 0.5;
			}
		}
		// 进位取整
		return Math.ceil(valueLength);
	}

	/**
	 * @author cn
	 * @param s      要截取的字符串
	 * @param length 要截取字符串的长度->是字节一个汉字2个字节 return 返回length长度的字符串（含汉字）
	 */
	public static String substring(String s, int length) throws Exception {

		byte[] bytes = s.getBytes("Unicode");
		int n = 0; // 表示当前的字节数
		int i = 2; // 要截取的字节数，从第3个字节开始
		for (; i < bytes.length && n < length; i++) {
			// 奇数位置，如3、5、7等，为UCS2编码中两个字节的第二个字节
			if (i % 2 == 1) {
				n++; // 在UCS2第二个字节时n加1
			} else {
				// 当UCS2编码的第一个字节不等于0时，该UCS2字符为汉字，一个汉字算两个字节
				if (bytes[i] != 0) {
					n++;
				}
			}

		}
		// 如果i为奇数时，处理成偶数
		/*
		 * if (i % 2 == 1){ // 该UCS2字符是汉字时，去掉这个截一半的汉字 if (bytes[i - 1] != 0) i = i - 1;
		 * // 该UCS2字符是字母或数字，则保留该字符 else i = i + 1; }
		 */
		// 将截一半的汉字要保留
		if (i % 2 == 1) {
			i = i + 1;
		}
		return new String(bytes, 0, i, "Unicode");
	}

	/**
	 * 保存文件
	 * 
	 * @param stream
	 * @param path
	 * @param filename
	 * @throws IOException
	 */
	public static void SaveFileFromInputStream(InputStream stream, String path, String filename) throws IOException {
		File f = new File(path);
		if (!f.exists()) {
			f.mkdirs();
		}

		FileOutputStream fs = new FileOutputStream(path + "/" + filename);
		byte[] buffer = new byte[1024 * 1024];
		int byteread = 0;
		while ((byteread = stream.read(buffer)) != -1) {

			fs.write(buffer, 0, byteread);
			fs.flush();
		}
		fs.close();
		stream.close();
	}

	/**
	 * 计算两个日期之间相差的天数
	 * 
	 * @param smdate 较小的时间
	 * @param bdate  较大的时间
	 * @return 相差天数
	 * @throws ParseException
	 */
	public static int daysBetween(Date smdate, Date bdate) throws ParseException {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		smdate = sdf.parse(sdf.format(smdate));
		bdate = sdf.parse(sdf.format(bdate));
		Calendar cal = Calendar.getInstance();
		cal.setTime(smdate);
		long time1 = cal.getTimeInMillis();
		cal.setTime(bdate);
		long time2 = cal.getTimeInMillis();
		long between_days = (time2 - time1) / (1000 * 3600 * 24);

		return Integer.parseInt(String.valueOf(between_days));
	}

	/**
	 * 字符串的日期格式的计算
	 */
	public static int daysBetween(String smdate, String bdate) throws ParseException {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Calendar cal = Calendar.getInstance();
		cal.setTime(sdf.parse(smdate));
		long time1 = cal.getTimeInMillis();
		cal.setTime(sdf.parse(bdate));
		long time2 = cal.getTimeInMillis();
		long between_days = (time2 - time1) / (1000 * 3600 * 24);

		return Integer.parseInt(String.valueOf(between_days));
	}

	static public void memset(byte[] src, byte ch, int offset, int len) {
		if (len <= 0 || src == null) {
			return;
		}

		if (offset < 0) {
			offset = 0;
		}

		if (offset + len > src.length) {
			return;
		}

		for (int i = offset; i < len; i++) {
			src[i] = ch;
		}

	}

	/**
	 * 内存比较
	 * 
	 * @param src
	 * @param srcpos
	 * @param dest
	 * @param destpos
	 * @param len
	 * @return
	 */
	public static int memcmp(byte[] src, int srcpos, byte[] dest, int destpos, int len) {
		for (int i = 0; i < len; i++) {
			int si = srcpos + i;
			int di = destpos + i;
			if (si >= src.length) {
				if (di >= dest.length) {
					return 0;
				} else {
					return -1;
				}

			} else if (di >= dest.length) {
				return 1;
			}

			int ret = src[si] - dest[di];
			if (ret != 0) {
				return ret;
			}

		}
		return 0;
	}

	/**
	 * 将字节转换为无符号数
	 * 
	 * @param b byte 字节值
	 * @return short 无符号数
	 */
	static public short byteToUnsigned(byte b) {
		short ret = b;
		if (b < 0) {
			ret += 256;
		}

		return ret;
	}

	/**
	 * 二进制字节数组转浮点数,一个浮点数占4个字节,应该保证b.length>=offset+4
	 * 
	 * @param b      byte[] 要转换二进制字节数组
	 * @param offset int 偏移量,即从字节数组的第几个几字开始转换
	 * @return float 转换后的浮点数
	 */
	static public float bytesToFloat(byte[] b, int offset) {
		return Float.intBitsToFloat(bytesToInt(b, offset));
	}

	/**
	 * 浮点数转换为二进制字节数组
	 * 
	 * @param f float 要转换浮点数
	 * @return byte[] 转换后的二进制字节数组
	 */
	static public byte[] floatToBytes(float f) {
		return intToBytes(Float.floatToIntBits(f));
	}

	/**
	 * 二进制字节数组转双精度浮点数,一个双精度浮点数占8个字节,应该保证b.length>=offset+8
	 * 
	 * @param b      byte[] 要转换二进制字节数组
	 * @param offset int 偏移量,即从字节数组的第几个几字开始转换
	 * @return float 转换后的双精度浮点数
	 */
	static public double bytesToDouble(byte[] b, int offset) {
		return Double.longBitsToDouble(bytesToLong(b, offset));
	}

	/**
	 * 双精浮点数转换为二进制字节数组
	 * 
	 * @param f float 要转换双精浮点数
	 * @return byte[] 转换后的二进制字节数组
	 */
	static public byte[] doubleToBytes(double f) {
		return longToBytes(Double.doubleToLongBits(f));
	}

	/**
	 * 二进制字节数组转长整数,一个长整数占8个字节,由于一个整数可以只占1~8个字节,本函数可以从 要转换的字节数组,提取1~8个字节来转换.
	 * 
	 * @param b      byte[] 要转换二进制字节数组
	 * @param offset int 偏移量,即从字节数组的第几个几字开始转换
	 * @param len    长度.将多少个字节转换成长整数
	 * @return long 转换后长整数
	 */
	static public long bytesToLong(byte[] b, int offset, int len) {
		long tmp = 0;
		long ret = 0;
		for (int i = 0; i < len; i++) {
			tmp = (b[offset + i] & 0xff);
			tmp = tmp << (i * 8);
			ret |= tmp;
		}
		return ret;
	}

	/**
	 * 二进制字节数组转长整数,一个长整数占8个字节,要确保b.length>=offset+8.
	 * 
	 * @param b      byte[] 要转换二进制字节数组
	 * @param offset int 偏移量,即从字节数组的第几个几字开始转换
	 * @return long 转换后长整数
	 */
	static public long bytesToLong(byte[] b, int offset) {
		return bytesToLong(b, offset, 8);
	}

	/**
	 * 长整数转换成二进制字节数组
	 * 
	 * @param long v 要转换的长整数
	 * @return byte[] 转换后的二进制字节数组
	 */
	static public byte[] longToBytes(long v) {
		byte[] ret = new byte[8];
		for (int i = 0; i < 8; i++) {
			ret[i] = (byte) ((v >> (i * 8)) & 0xff);
		}
		return ret;
	}

	/**
	 * 长整数转换成二进制字节数组,只转换低len位字节
	 * 
	 * @param     long v 要转换的长整数
	 * @param len 转换后的字节长度
	 * @return byte[] 转换后的二进制字节数组
	 */
	static public byte[] longToBytes(long v, int len) {
		byte[] ret = new byte[len];
		for (int i = 0; i < len; i++) {
			ret[i] = (byte) ((v >> (i * 8)) & 0xff);
		}
		return ret;
	}

	/**
	 * 二进制字节数组转换成整数,应确保b.length>=offset+4
	 * 
	 * @param b      byte[] 字节数组
	 * @param offset int 转换偏移量,基于字节数组b
	 * @return long 转换后的整数
	 */
	static public int bytesToInt(byte[] b, int offset) {
		return (int) bytesToLong(b, offset, 4);
	}

	/**
	 * 整数转换成二进制字节数组
	 * 
	 * @param int v 要转换的整数
	 * @return byte[] 转换后的二进制字节数组
	 */
	static public byte[] intToBytes(int v) {
		byte[] ret = new byte[4];
		for (int i = 0; i < 4; i++) {
			ret[i] = (byte) ((v >> (i * 8)) & 0xff);
		}
		return ret;
	}

	/**
	 * 二进制字节数组转换成短整数
	 * 
	 * @param b      byte[] 二进制字节数组
	 * @param offset int 转换偏移量
	 * @return long 转换后的短整数
	 */
	static public short bytesToShort(byte[] b, int offset) {
		return (short) bytesToLong(b, offset, 2);
	}

	/**
	 * 短整数转换成二进制字节数组
	 * 
	 * @param short v 要转换的短整数
	 * @return byte[] 转换后的二进制字节数组
	 */
	static public byte[] shortToBytes(short v) {
		byte[] ret = new byte[2];
		for (int i = 0; i < 2; i++) {
			ret[i] = (byte) ((v >> (i * 8)) & 0xff);
		}
		return ret;
	}

	/**
	 * 字节反相输出,即高位字节和低位字节互换
	 * 
	 * @param b      byte[] 字节数组
	 * @param offset 偏移量
	 * @param len    转换长度
	 * @return byte[] 反相输出后的字节数组
	 */
	static public byte[] bytesReverse(byte[] b, int offset, int len) {
		byte[] ret = new byte[len];
		for (int i = 0; i < len; i++) {
			ret[i] = b[len + offset - i - 1];
		}

		return ret;
	}

	/**
	 * 将主机字节的整数转换为网络字节的整数
	 * 
	 * @param b int 主机字节的整数
	 * @return int 网络字节的整数
	 */
	static int htonl(int b) {
		return htonl(intToBytes(b), 0);
	}

	/**
	 * 将主机字节的二进制字节数组转换为网络字节的整数,应确保b.length>=offset+4
	 * 
	 * @param b      int 主机字节数组
	 * @param offset int 转换字节数组的偏移量
	 * @return int 网络字节的整数
	 */
	static int htonl(byte[] b, int offset) {
		return bytesToInt(bytesReverse(b, offset, 4), 0);
	}

	/**
	 * 将主机字节的整数转换为网络字节的短整数
	 * 
	 * @param b int 主机字节的整数
	 * @return int 网络字节的整数
	 */
	static short htons(short b) {
		return htons(shortToBytes(b), 0);
	}

	/**
	 * 将主机字节的二进制字节数组转换为网络字节的短整数,应确保b.length>=offset+2
	 * 
	 * @param b      int 主机字节数组
	 * @param offset int 转换字节数组的偏移量
	 * @return int 网络字节的整数
	 */
	static short htons(byte[] b, int offset) {
		return bytesToShort(bytesReverse(b, offset, 2), 0);
	}

	/**
	 * 将网络字节的整数转换为主机字节的整数
	 * 
	 * @param b int 网络字节的整数
	 * @return int 主机字节的整数
	 */
	static int ntohl(int b) {
		return ntohl(intToBytes(b), 0);
	}

	/**
	 * 将网络字节的二进制字节数组转换为主机字节的整数,应确保b.length>=offset+4
	 * 
	 * @param b      int 网络字节数组
	 * @param offset int 转换字节数组的偏移量
	 * @return int 主机字节的整数
	 */
	static int ntohl(byte[] b, int offset) {
		return bytesToInt(bytesReverse(b, offset, 4), 0);
	}

	/**
	 * 将网络字节的整数转换为主机字节的短整数
	 * 
	 * @param b int 网络字节的整数
	 * @return int 主机字节的整数
	 */
	static short ntohs(short b) {
		return ntohs(shortToBytes(b), 0);
	}

	/**
	 * 将网络字节的二进制字节数组转换为主机字节的短整数,应确保b.length>=offset+2
	 * 
	 * @param b      int 网络字节数组
	 * @param offset int 转换字节数组的偏移量
	 * @return int 主机网络字节的整数
	 */
	static short ntohs(byte[] b, int offset) {
		return bytesToShort(bytesReverse(b, offset, 2), 0);
	}

	/**
	 * 字节转换为16进制字符串
	 * 
	 * @param ch byte 要转换的字节
	 * @return String 16进制字符串
	 */
	static public String intToHex(int number) {
		return Integer.toHexString(number);
	}

	/**
	 * 字节转换为16进制字符串
	 * 
	 * @param ch byte 要转换的字节
	 * @return String 16进制字符串
	 */
	static public String byteToHex(byte ch) {
		String [] str = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F" };
		return str[ch >> 4 & 0xF] + str[ch & 0xF];
	}

	/**
	 * 二进制字节数组转换为16进制字符串
	 *
	 * @param ch byte[] 二进制字节数组
	 * @return String 16进制字串
	 */
	static public String bytesToHex(byte[] ch) {
		StringBuffer  ret = new StringBuffer ();
		for (int i = 0; i < ch.length; i++) {
			ret.append(byteToHex(ch[i]));
		}
		return ret.toString();
	}

	/**
	 * 二进制字节数组转换为16进制字符串
	 *
	 * @param ch byte[] 二进制字节数组
	 * @return String 16进制字串
	 */
	static public String bytesToHex(byte[] ch, int offset, int length) {
		StringBuffer  ret = new StringBuffer ();
		for (int i = 0; i < length; i++) {
			ret.append(byteToHex(ch[i + offset]));
		}
		return ret.toString();
	}

	/**
	 * 16进制字串转换为字节
	 * 
	 * @param str String 16进制字串
	 * @return byte 转换后的字节
	 */
	static public byte hexToByte(String str) {
		if (str.length() < 2) {
			return 0;
		}
		str = str.toUpperCase();
		byte[] bs = str.getBytes();
		byte l = 0, h = 0;
		l = bs[1];
		h = bs[0];
		if (l >= '0' && l <= '9') {
			l -= '0';
		} else if (l >= 'A' && l <= 'F') {
			l -= 'A';
			l += 10;
		} else {
			l = 0;
		}
		if (h >= '0' && h <= '9') {
			h -= '0';
		} else if (h >= 'A' && h <= 'F') {
			h -= 'A';
			h += 10;
		} else {
			h = 0;
		}
		h = (byte) (h << 4);
		return (byte) (h | l);
	}

	/**
	 * 16进制字节符串转换为二进制字节数组
	 * 
	 * @param str String 16进制字串
	 * @return byte[] 二进制字节数组
	 */
	static public byte[] hexToBytes(String str) {
		int len = str.length() / 2;
		str = str.toUpperCase();
		byte[] bs = str.getBytes();
		byte[] ret = new byte[len];
		for (int i = 0; i < len * 2; i += 2) {
			byte l = 0, h = 0;
			l = bs[i + 1];
			h = bs[i];
			if (l >= '0' && l <= '9') {
				l -= '0';
			}

			else if (l >= 'A' && l <= 'F') {
				l -= 'A';
				l += 10;
			} else {
				l = 0;
			}

			if (h >= '0' && h <= '9') {
				h -= '0';
			} else if (h >= 'A' && h <= 'F') {
				h -= 'A';
				h += 10;
			} else {
				h = 0;
			}

			h = (byte) (h << 4);
			ret[i / 2] = (byte) (h | l);
		}
		return ret;
	}

	/**
	 * bcd码转换为10进制字符串
	 *
	 * @param bcd byte[] bcd字节数组
	 * @param len int 要转换的长度
	 * @return String 转换后的字符串
	 */
	static public String bcdToDec(byte[] bcd, int offset, int len) {
		if (len <= 0 || len > bcd.length) {
			len = bcd.length;
		}
		StringBuffer ret = new StringBuffer();
		for (int i = 0; i < len; i++) {
			String str = byteToHex(bcd[offset + i]);
			ret.append(str);
		}
		return ret.toString();
	}

	/**
	 * 10进制字串转换为bcd码
	 * 
	 * @param s   String 10进制字串
	 * @param len int 转换长度
	 * @return byte[] 转换后的字节数组
	 * @throws IOException 转换失败后抛出
	 */
	static public byte[] decToBcd(String s, int len) throws IOException {
		if ((s.length() % 2) != 0) {
			s = "0" + s;
		}

		byte[] bs = s.getBytes();
		if (len <= 0) {
			len = bs.length;
		}

		if (len > bs.length) {
			len = bs.length;
		}

		len = len / 2;
		byte[] ret = new byte[len];
		for (int i = 0; i < len; i++) {
			byte c = (byte) (bs[i * 2] - '0');
			byte c1 = (byte) (bs[i * 2 + 1] - '0');
			if (c < 0 || c > 9 || c1 > 9 || c1 < 0) {
				throw new IOException("不是有效的数字!");
			}
			ret[i] = (byte) (c << 4 | c1);
		}
		return ret;
	}

	/**
	 * 元转换为分
	 * 
	 * @param src String 原始字串
	 * @return int 转换后整数,以分为单位
	 */
	static public int yuanToFen(String src) {
		src = src.trim();
		if (src.length() == 0) {
			return 0;
		}

		int f = 1;
		if (src.getBytes()[0] == '-') {
			f = -1;
			src = src.substring(1);
		}
		int r = 0;
		if (src.length() > 0) {
			int pos = src.indexOf(".");
			if (pos < 0) {
				r = Integer.parseInt(src);
			} else {
				String s = src.substring(0, pos);
				src = src.substring(pos + 1);
				int len = src.length();
				if (len > 2) {
					src = src.substring(0, 2);
				}

				else if (len == 0) {
					src = "00";
				}

				else if (len == 1) {
					src = src + "0";
				}

				r = Integer.parseInt(s + src);
			}
		}
		return r * f;
	}

	/**
	 * 分转换为元
	 * 
	 * @param src int 分
	 * @return String 元
	 */
	static public String fenToYuan(int src) {
		String f = "";
		if (src < 0) {
			f = "-";
			src = -src;
		}
		if (src < 10) {
			return f + "0.0" + Integer.toString(src);
		}

		else if (src < 100) {
			return f + "0." + Integer.toString(src);
		}

		else {
			int i = src / 100;
			int s = src % 100;
			if (s < 10) {
				return f + Integer.toString(i) + ".0" + Integer.toString(s);
			} else {
				return f + Integer.toString(i) + "." + Integer.toString(s);
			}
		}
	}

	/**
	 * 分转换为元
	 * 
	 * @param src int 分
	 * @return String 元
	 */
	static public String fenToYuan(long src) {
		String f = "";
		if (src < 0) {
			f = "-";
			src = -src;
		}
		if (src < 10) {
			return f + "0.0" + Long.toString(src);
		} else if (src < 100) {
			return f + "0." + Long.toString(src);
		} else {
			long i = src / 100;
			long s = src % 100;
			if (s < 10) {
				return f + Long.toString(i) + ".0" + Long.toString(s);
			} else {
				return f + Long.toString(i) + "." + Long.toString(s);
			}
		}
	}

	/**
	 * 分转换为元
	 * 
	 * @param srcStr String 分
	 * @return String 元
	 */
	static public String fenToYuan(String srcStr) {
		int src = 0;
		srcStr = srcStr.trim();
		if (srcStr.length() > 0) {
			src = Integer.parseInt(srcStr);
		}
		String f = "";
		if (src < 0) {
			f = "-";
			src = -src;
		}
		if (src < 10) {
			return f + "0.0" + Integer.toString(src);
		} else if (src < 100) {
			return f + "0." + Integer.toString(src);
		} else {
			int i = src / 100;
			int s = src % 100;
			if (s < 10) {
				return f + Integer.toString(i) + ".0" + Integer.toString(s);
			} else {
				return f + Integer.toString(i) + "." + Integer.toString(s);
			}
		}
	}

	public static String trimRight(String str) {
		int len = str.length();
		for (int i = len - 1; i >= 0; i--) {
			if (str.charAt(i) > ' ') {
				return str.substring(0, i + 1);
			}
		}
		return "";
	}

	public static String trimLeft(String str) {
		int len = str.length();
		for (int i = 0; i < len; i++) {
			if (str.charAt(i) > ' ') {
				return str.substring(i);
			}
		}
		return "";
	}

	static public boolean isVisibleChar(byte c) {
		switch (c) {
		case '.':
		case ',':
		case '>':
		case '<':
		case '?':
		case '/':
		case '\'':
		case ';':
		case ':':
		case '\"':
		case '\\':
		case '|':
		case ']':
		case '[':
		case '}':
		case '{':
		case '-':
		case '_':
		case '+':
		case '=':
		case ')':
		case '(':
		case '*':
		case '&':
		case '^':
		case '%':
		case '$':
		case '#':
		case '@':
		case '!':
		case '`':
		case '~':
		case ' ':
			return true;
		default:
			if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9')) {
				return true;
			} else if (c < 0) {
				return true;
			} else {
				return false;
			}
		}
	}

	public static String[] formatHex(byte[] data) {
		if (data == null || data.length == 0) {
			return new String[0];
		}
		int len = data.length;
		int rows = len / 16 + (len % 16 > 0 ? 1 : 0);
		String[] ret = new String[rows];
		for (int i = 0; i < rows; i++) {
			String str = "";
			byte bb[] = null;
			if (len >= (i + 1) * 16) {
				bb = new byte[16];
			} else {
				bb = new byte[len - i * 16];
			}
			for (int j = 0; j < bb.length; j++) {
				byte b = data[i * 16 + j];
				str += byteToHex(b) + " ";
				if (j == i * 16 + 8) {
					str += " ";
				}
				if (!isVisibleChar(b)) {
					bb[j] = '.';
				} else {
					bb[j] = b;
				}
			}
			String a = Integer.toHexString(i * 16);
			while (a.length() < 8) {
				a = "0" + a;
			}
			while (str.length() < 49) {
				str += " ";
			}
			ret[i] = a + "h: " + str + "; " + new String(bb);
		}
		return ret;
	}

	public static Object checkNull(Object src, Object def) {
		if (src == null) {
			return def;
		} else {
			return src;
		}
	}

	/**
	 * 返回字符串src的前len个字串（以字节为单位计数）
	 * 
	 * @param src
	 * @param len
	 * @return
	 */
	public static String checkBytesLength(String src, int len) {
		if (src == null) {
			return "";
		}
		if (src.getBytes().length < len) {
			return src;
		}
		int l = 0;
		for (int i = 0; i < src.length(); i++) {
			char c = src.charAt(i);
			if (c > 255) {
				l += 2;
			} else {
				l += 1;
			}
			if (l == len) {
				return src.substring(0, i + 1);
			} else if (l > len) {
				return src.substring(0, i);
			}
		}
		return src;
	}
}